﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "GcmpModel.h"
#include "IObject.h"

namespace gcmp
{
    class IDocument;

    /// \brief 自定义事务结束时处理器接口
    ///
    /// 实现自定义事务结束处理器后， 可使用以下两个接口将处理器注册到平台中
    ///     在事务结束，更新文档前触发：UserTransactionUtils::AddEndofProcessorBeforeRegenerateAll
    ///     在事务结束，更新文档后触发：UserTransactionUtils::AddEndofProcessorAfterRegenerateAll
    ///     
    class GCMP_MODEL_EXPORT IEndOfTransactionProcessor:public IObject
    {
        DEFINE_CAST_DERIVED(gcmp::IEndOfTransactionProcessor, gcmp::IObject);
    public:
        /// \brief 创建一个新的处理器Id, 该Id是唯一的
        ///
        /// \return 创建出来的处理器id
        static Int64 GenerateId();

    public:
        /// \brief 获取当前处理器的id
        ///
        /// 除非在使用时能保证GetId获取到的id的唯一性， 
        /// 否则GetId返回的id应是通过CreateNewId创建的
        ///
        /// \return 处理器id
        virtual Int64 GetId() const = 0;

        /// \brief 结束事务时的自定义操作入口
        ///
        /// 无论是在自定义操作位于自定义文档之前还是之后，都不应该对事
        /// 务本身做包括Rollback和Commit之类的修改。 也不应该在这里创建新事务。
        ///
        /// 另外，当该Processor被用于更新文档之前时， 你依旧可以对相关Element数据做更改，
        /// 因为这个时候还未进行更新文档，但被用于之后时，自定义操作中应当包含的是一些通知
        /// 或者基于观察变化相关的操作， 而不是在这个里面对Element相关的数据做更改，
        /// 因为这个时候文档已经完成了更新。
        ///
        /// \param pDoc 文档指针
        virtual void Process(IDocument* pDoc) = 0;

        /// \brief 析构函数
        virtual ~IEndOfTransactionProcessor() {}
    };
}

